package com.kehutong.common.util;

import org.coraframework.util.Objects;

import java.math.BigDecimal;

/**
 * BigDecimal 货币类型常规计算
 *
 * @author jian Ye
 * @date: 2021-08-17
 */
public class BigDecimalUtils {

    /**全局保留小数点位数*/
    final static int GLOBAL_SCALE = 2;

    private static Integer defaultScale(Integer scale) {
        if (null == scale) {
            scale = GLOBAL_SCALE;
        }
        return scale;
    }

    /**
     * 格式化货币类型，自行设置保留位数
     * @param bigDecimal
     * @param scale 保留小数点位数
     * @return
     */
    public static BigDecimal format(BigDecimal bigDecimal, int scale) {
        if (bigDecimal == null) {
            bigDecimal = new BigDecimal(0);
        }
        return bigDecimal.setScale(scale, BigDecimal.ROUND_UP);
    }

    /**
     * 格式化货币类型，默认保留2位小数
     * @param bigDecimal
     * @return
     */
    public static BigDecimal format(BigDecimal bigDecimal) {
        if (bigDecimal == null) {
            bigDecimal = new BigDecimal(0);
        }
        return bigDecimal.setScale(GLOBAL_SCALE, BigDecimal.ROUND_UP);
    }

    /**
     * String转换成BigDecimal
     * @param bigDecimal
     * @return
     */
    public static BigDecimal format(String bigDecimal) {
        String reg = "^[0-9]+(.[0-9]+)?$";
        if (Objects.isBlank(bigDecimal) || !bigDecimal.matches(reg)) {
            return new BigDecimal(0).setScale(GLOBAL_SCALE, BigDecimal.ROUND_UP);
        }
        return new BigDecimal(bigDecimal).setScale(GLOBAL_SCALE, BigDecimal.ROUND_UP);
    }


    /**
     * 格式化返回String
     * @param bigDecimal
     * @return
     */
    public static String parse(BigDecimal bigDecimal){
        if (bigDecimal == null) {
            bigDecimal = new BigDecimal(0);
        }
        return format(bigDecimal).toPlainString();
    }


    /**
     * 格式化返回String
     * @param bigDecimal
     * @return
     */
    public static String parse(String bigDecimal){
        if (Objects.isEmpty(bigDecimal)) {
            bigDecimal = "0";
        }
        return format(bigDecimal).toPlainString();
    }


    /**
     * 乘法，自定义保留小数位
     * @param bigDecimal
     * @param number
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal mul(BigDecimal bigDecimal, int number, int scale) {
        scale = defaultScale(scale);

        if (bigDecimal == null) {
            bigDecimal = format(new BigDecimal(0));
        }
        return format(bigDecimal.multiply(BigDecimal.valueOf(number)),scale);
    }

    /**
     * 乘法，自定义保留小数位
     * @param bigDecimal
     * @param number
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal mul(BigDecimal bigDecimal, double number, int scale) {
        scale = defaultScale(scale);

        if (bigDecimal == null) {
            bigDecimal = format(new BigDecimal(0));
        }
        return format(bigDecimal.multiply(BigDecimal.valueOf(number)),scale);
    }


    /**
     * 乘法，自定义保留小数位
     * @param bigDecimal
     * @param number
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal mul(BigDecimal bigDecimal, BigDecimal number, int scale) {
        scale = defaultScale(scale);

        if (bigDecimal == null) {
            bigDecimal = format(new BigDecimal(0));
        }
        return format(bigDecimal.multiply(number),scale);
    }


    /**
     * 加法，自定义保留小数位
     * @param bigDecimal1
     * @param bigDecimal2
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal add(BigDecimal bigDecimal1, BigDecimal bigDecimal2, int scale) {
        scale = defaultScale(scale);
        if (bigDecimal1 == null) {
            bigDecimal1 = format(new BigDecimal(0));
        }
        if (bigDecimal2 == null) {
            bigDecimal2 = format(new BigDecimal(0));
        }
        return format(bigDecimal1.add(bigDecimal2),scale);
    }

    /**
     * 加法，不保留小数位
     * @param bigDecimal1
     * @param bigDecimal2
     * @return
     */
    public static BigDecimal add(BigDecimal bigDecimal1, BigDecimal bigDecimal2) {
        if (bigDecimal1 == null) {
            bigDecimal1 = format(new BigDecimal(0));
        }
        if (bigDecimal2 == null) {
            bigDecimal2 = format(new BigDecimal(0));
        }
        return bigDecimal1.add(bigDecimal2);
    }

    /**
     * 减法，自定义保留小数位
     * @param bigDecimal1
     * @param bigDecimal2
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal sub(BigDecimal bigDecimal1, BigDecimal bigDecimal2, int scale) {
        scale = defaultScale(scale);
        if (bigDecimal1 == null) {
            bigDecimal1 = format(new BigDecimal(0));
        }
        if (bigDecimal2 == null) {
            bigDecimal2 = format(new BigDecimal(0));
        }
        return format(bigDecimal1.subtract(bigDecimal2),scale);
    }

    /**
     * 除法，自定义保留小数位
     * @param bigDecimal
     * @param number
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal div(BigDecimal bigDecimal, int number, int scale) {
        scale = defaultScale(scale);
        if (bigDecimal == null) {
            bigDecimal = format(new BigDecimal(0));
        }
        return bigDecimal.divide(BigDecimal.valueOf(number), scale, BigDecimal.ROUND_UP);
    }

    /**
     * 除法，自定义保留小数位
     * @param bigDecimal
     * @param number
     * @param scale 结果保留小数点位数（直接截取，不做四舍五入）
     * @return
     */
    public static BigDecimal div(BigDecimal bigDecimal, BigDecimal number, int scale) {
        scale = defaultScale(scale);
        if (bigDecimal == null) {
            bigDecimal = format(new BigDecimal(0));
        }
        return bigDecimal.divide(number, scale, BigDecimal.ROUND_UP);
    }

    /**
     * 等于
     * @param leftNum 比数
     * @param rightNum 被比标量
     * @return 相等返回true
     */
    public static boolean isEquals(BigDecimal leftNum, BigDecimal rightNum) {
        if (leftNum == null) {
            leftNum = BigDecimal.ZERO;
        }
        if (rightNum == null) {
            rightNum = BigDecimal.ZERO;
        }
        if (leftNum.compareTo(rightNum)==0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 小于
     * @param leftNum 比数
     * @param rightNum 被比标量
     * @return 如果左边小于右边返回true
     */
    public static boolean isLessThan(BigDecimal leftNum, BigDecimal rightNum) {
        if (leftNum == null) {
            leftNum = BigDecimal.ZERO;
        }
        if (rightNum == null) {
            rightNum = BigDecimal.ZERO;
        }
        int r = leftNum.compareTo(rightNum);
        if (r == -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 小于等于
     * @param leftNum 比数
     * @param rightNum 被比标量
     * @return
     */
    public static boolean isLessThanOrEquals(BigDecimal leftNum, BigDecimal rightNum) {
        if (leftNum == null) {
            leftNum = BigDecimal.ZERO;
        }
        if (rightNum == null) {
            rightNum = BigDecimal.ZERO;
        }
        int r = leftNum.compareTo(rightNum);
        if (r == -1 || r == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 大于
     * @param leftNum 比数
     * @param rightNum 被比标量
     * @return 如果左边大于右边返回true
     */
    public static boolean isGreaterThan(BigDecimal leftNum, BigDecimal rightNum) {
        if (leftNum == null) {
            leftNum = BigDecimal.ZERO;
        }
        if (rightNum == null) {
            rightNum = BigDecimal.ZERO;
        }
        int r = leftNum.compareTo(rightNum);
        if (r == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 大于等于
     * @param leftNum 比数
     * @param rightNum 被比标量
     * @return 如果左边大于等于右边返回true
     */
    public static boolean isGreaterThanOrEquals(BigDecimal leftNum, BigDecimal rightNum) {
        if (leftNum == null) {
            leftNum = BigDecimal.ZERO;
        }
        if (rightNum == null) {
            rightNum = BigDecimal.ZERO;
        }
        int r = leftNum.compareTo(rightNum);
        if (r == 1 || r == 0) {
            return true;
        } else {
            return false;
        }
    }


}
